﻿using AutoUpdaterDotNET;
using DataSyncCom;
using DataSyncCommon;
using DataSyncCommon.Model;
using Newtonsoft.Json;
using Quartz;
using Quartz.Impl;
using Serilog.Core;
using System;
using System.Data;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleSub
{
    public class Service
    {
        Logger logger;
        public async void StartAsync()
        {
            logger = LogHelper.CreateLoger();
            logger.Error(" 服务启动 ");
            GetConfig();
            //#if !DEBUG
            addtype();
            //#endif
            await Task.Run(() => CreateMonitorJob());
            await Task.Run(() => CreatDownJob());
            await Task.Run(() => CreateUpJob());
            var cs = new CSRedis.CSRedisClient("43.254.3.211:6379,password=Abcd1234");
            cs.Subscribe((SysConfig.TenantId.ToString(), msg =>
            {
                logger.Error($"我[{SysConfig.TenantId}]接收到消息了:"+msg.Body);
                switch (msg.Body)
                {
                    case "1":
                        UploadData();
                        break;
                    case "2":
                        DownData();
                        break;
                    case "3":
                        GetIpconfig();
                        break;
                    case "1000":
                        Updata();
                        break;
                    default: break;
                }
            }
            ));
        }

        private void addtype()
        {
            try
            {
                string pd = "select count(*) from information_schema.columns where table_name='order_no' and " +
                       "COLUMN_NAME='ADD_TYPE' AND TABLE_SCHEMA='barcodenew'";
                DataSet ds = null;
                DbHelperMySql.ExecuteQueryByConnstr(SysConfig.ConnectionStr, pd, out ds);
                if (Convert.ToInt32(ds.Tables[0].Rows[0][0]) != 0) return;

                string sql = @"ALTER TABLE `order_no`
ADD COLUMN `ADD_TYPE`  int DEFAULT 0 NULL COMMENT '0：默认新增值，1：已经上传';

ALTER TABLE `order_manage`
ADD COLUMN `ADD_TYPE`  int DEFAULT 0 NULL COMMENT '0：默认新增值，1：已经上传';

ALTER TABLE `order_manage_list`
ADD COLUMN `ADD_TYPE`  int DEFAULT 0 NULL COMMENT '0：默认新增值，1：已经上传';

ALTER TABLE `pp_big_lab_sup`
ADD COLUMN `ADD_TYPE`  int DEFAULT 0 NULL COMMENT '0：默认新增值，1：已经上传';

ALTER TABLE `pp_lab_lst_sup`
ADD COLUMN `ADD_TYPE`  int DEFAULT 0 NULL COMMENT '0：默认新增值，1：已经上传';

ALTER TABLE `ba_material` MODIFY COLUMN `MAT_TYPE_ID` varchar(40) CHARACTER SET utf8 COLLATE utf8_general_ci NULL;
ALTER TABLE `pp_big_lab_sup` MODIFY COLUMN `big_mat_unit` varchar(40) CHARACTER SET utf8 COLLATE utf8_general_ci NULL;
ALTER TABLE `pp_lab_lst_sup` MODIFY COLUMN `big_mat_unit` varchar(40) CHARACTER SET utf8 COLLATE utf8_general_ci NULL;
                            ";
                ds = null;
                DbHelperMySql.ExecuteQueryByConnstr(SysConfig.ConnectionStr, sql, out ds);
                sql = @"update `order_no` set `ADD_TYPE`=0;
update `order_manage` set `ADD_TYPE`= 0;
            update `order_manage_list` set `ADD_TYPE`= 0;
            update `pp_big_lab_sup` set `ADD_TYPE`= 0;
            update `pp_lab_lst_sup` set `ADD_TYPE`= 0; ";
                ds = null;
                DbHelperMySql.ExecuteQueryByConnstr(SysConfig.ConnectionStr, sql, out ds);
                logger.Error("addtype成功" );
            }
            catch (Exception ex)
            {
                logger.Error("addtype失败"+ex.Message);
                throw;
            }
        }

        public async Task CreateMonitorJob() {
            logger.Error("------- Initializing ----------------------");
            // First we must get a reference to a scheduler
            ISchedulerFactory sf = new StdSchedulerFactory();
            IScheduler sched = await sf.GetScheduler();
            logger.Error("------- Initialization Complete -----------");
            // computer a time that is on the next round minute
            DateTimeOffset runTime = DateBuilder.EvenMinuteDate(DateTimeOffset.UtcNow);
            logger.Error("------- Scheduling Job  -------------------");
            // define the job and tie it to our HelloJob class
            IJobDetail job = JobBuilder.Create<MonitorJob>()
                .WithIdentity("MonitorJob", "group1")
                .Build();
            // Trigger the job to run on the next round minute
            ITrigger trigger = TriggerBuilder.Create()
                .WithIdentity("MonitorJobtrigger1", "group1")
                .StartNow()
                .WithSimpleSchedule(x => x.WithIntervalInMinutes(SysConfig.monitorjob).RepeatForever())//设置任务时间并且永远重复
                .Build();
            // Tell quartz to schedule the job using our trigger
            await sched.ScheduleJob(job, trigger);
            logger.Error($"{job.Key} will run at: {runTime:r}");
            // Start up the scheduler (nothing can actually run until the
            // scheduler has been started)
            await sched.Start();
            logger.Error("------- Started Scheduler -----------------");
        }
        /// <summary>
        /// 创建上传数据任务
        /// </summary>
        public async Task CreateUpJob() {
            logger.Error("------- Initializing ----------------------");
            // First we must get a reference to a scheduler
            ISchedulerFactory sf = new StdSchedulerFactory();
            IScheduler sched = await sf.GetScheduler();
            logger.Error("------- Initialization Complete -----------");
            // computer a time that is on the next round minute
            DateTimeOffset runTime = DateBuilder.EvenMinuteDate(DateTimeOffset.UtcNow);
            logger.Error("------- Scheduling Job  -------------------");
            // define the job and tie it to our HelloJob class
            IJobDetail job = JobBuilder.Create<UpData>()
                .WithIdentity("UpDatajob", "group1")
                .Build();
            // Trigger the job to run on the next round minute
            ITrigger trigger = TriggerBuilder.Create()
                .WithIdentity("UpDatajobtrigger1", "group1")
                .StartNow()
                .WithSimpleSchedule(x => x.WithIntervalInMinutes(SysConfig.upbusjob).RepeatForever())
                .Build();
            // Tell quartz to schedule the job using our trigger
            await sched.ScheduleJob(job, trigger);
            logger.Error($"{job.Key} will run at: {runTime:r}");
            // Start up the scheduler (nothing can actually run until the
            // scheduler has been started)
            await sched.Start();
            logger.Error("------- Started Scheduler -----------------");
        }
        /// <summary>
        /// 创建下载基础数据任务
        /// </summary>
        /// <returns></returns>
        public async Task CreatDownJob() {
            logger.Error("------- Initializing ----------------------");
            // First we must get a reference to a scheduler
            ISchedulerFactory sf = new StdSchedulerFactory();
            IScheduler sched = await sf.GetScheduler();
            logger.Error("------- Initialization Complete -----------");
            // computer a time that is on the next round minute
            DateTimeOffset runTime = DateBuilder.EvenMinuteDate(DateTimeOffset.UtcNow);
            logger.Error("------- Scheduling Job  -------------------");
            // define the job and tie it to our HelloJob class
            IJobDetail job = JobBuilder.Create<DownData>()
                .WithIdentity("DownDatajob", "group1")
                .Build();
            // Trigger the job to run on the next round minute
            ITrigger trigger = TriggerBuilder.Create()
                .WithIdentity("DownDatajobtrigger", "group1")
                .StartNow()
                .WithSimpleSchedule(x => x.WithIntervalInHours(24 * SysConfig.downbasejob).RepeatForever())//下载数据1天*变量
                //.WithSimpleSchedule(x => x.WithIntervalInMinutes(SysConfig.downbasejob).RepeatForever())//下载数据分钟用于测试
                .Build();
            // Tell quartz to schedule the job using our trigger
            await sched.ScheduleJob(job, trigger);
            logger.Error($"{job.Key} will run at: {runTime:r}");
            // Start up the scheduler (nothing can actually run until the
            // scheduler has been started)
            await sched.Start();
            logger.Error("------- Started Scheduler -----------------");
            //// wait long enough so that the scheduler as an opportunity to
            //// run the job!
            //logger.Error("------- Waiting 65 seconds... -------------");

            //// wait 65 seconds to show jobs
            //await Task.Delay(TimeSpan.FromSeconds(65));

            //// shut down the scheduler
            //logger.Error("------- Shutting Down ---------------------");
            //await sched.Shutdown(true);
            //logger.Error("------- Shutdown Complete -----------------");
        }
        public async void GetIpconfig()
        {
            logger.Error("获取IP地址");
            var config = await HttpHelper.GetIpconfig();
            var regex = new Regex(@"(\d+\.\d+\.\d+\.\d+)");
            var match = regex.Match(config);
            var ip = "";
            if (match.Success)
            {
                ip = match.Groups[0].Value;
                Console.WriteLine($"外网IP地址为:{ip}");
            }
            var log = new ba_sup_log()
            {
                SYS_USER_CD = "a",
                SYS_CODE = "online",
                LOGIN_IP = ip,
                NOTE = config.Split('=')[1].Trim().Trim(';'),
                TenantId = Convert.ToInt32(ConfigManager.GetValue("tenantid"))
            };
            var responseStr=LogHelper.InDbLog(log);
            logger.Error($"执行获取IP地址成功写入日志{responseStr}");
        }
        public void GetConfig()
        {
            try
            {
                logger.Error(" 获取配置文件 ");
                string webApi = ConfigManager.GetValue("webapi") + "";
                string timeOutStr = ConfigManager.GetValue("timeout") + "";
                var conStr = "Data Source='{0}';Port='{1}';User Id='{2}';Password='{3}';Database='{4}';pooling=true;character set=utf8;";
                SysConfig.ClientIP = ConfigManager.GetValue("host");
                SysConfig.ClientPort = ConfigManager.GetValue("port");
                SysConfig.ClientUser = ConfigManager.GetValue("user");
                SysConfig.ClientPwd = ConfigManager.GetValue("pwd");
                SysConfig.ClientDbName = ConfigManager.GetValue("dbname");
                SysConfig.seraddress = webApi;
                SysConfig.SyncBusinessApiUrl = SysConfig.seraddress + ":5007/SupForOut/SupDataSync/SyncBusinessDataNow";//同步新打条码数据
                SysConfig.url= string.Join(":", webApi, SysConfig.port); ;
                conStr = string.Format(conStr, SysConfig.ClientIP, SysConfig.ClientPort, SysConfig.ClientUser, SysConfig.ClientPwd, SysConfig.ClientDbName);
                SysConfig.TenantId = Convert.ToInt32(ConfigManager.GetValue("tenantid"));
                SysConfig.downbasejob = Convert.ToInt32(ConfigManager.GetValue("downbasejob"));
                SysConfig.upbusjob = Convert.ToInt32(ConfigManager.GetValue("upbusjob"));
                SysConfig.monitorjob = Convert.ToInt32(ConfigManager.GetValue("monitorjob"));
                SysConfig.ConnectionStr = conStr;
            }
            catch (Exception ex)
            {
                logger.Error("获取配置文件失败"+ex.Message);
            }
        }
        /// <summary>
        /// 升级有问题，需要将服务关闭才行
        /// </summary>
        public void Updata()
        {
            try
            {
                logger.Error(" 服务升级 ");
                AutoUpdater.Synchronous = true;
                AutoUpdater.RunUpdateAsAdmin = true;
                AutoUpdater.OpenDownloadPage = true;
                AutoUpdater.Mandatory = true;
                AutoUpdater.UpdateMode = Mode.ForcedDownload;//直接下载替换 
                AutoUpdater.Start("http://xinghecloud.cn:81/AutoUpdater.xml");
            }
            catch (Exception ex)
            {
                logger.Error(ex.Message);
                throw;
            }
        }

        /// <summary>
        /// 上传数据
        /// </summary>
        public void UploadData()
        {
            logger.Error(" 上传数据 ");
            logger.Error(" 上传数据完成 ");
        }
        /// <summary>
        /// 下载数据
        /// </summary>
        public void DownData()
        {
            logger.Error(" 下载数据 ");
            DownData downData = new DownData();
            downData.down();
            logger.Error(" 下载数据完成 ");
        }
        public void Stop()
        {
            logger.Error("服务停止");
        }
    }

}

